grammar BasicArithmeticEqu;

options {
  language = Java;
  output = AST;
  ASTLabelType = CommonTree;
}

tokens{
  NEGATION;
}

@header {
  package arith;
}

@lexer::header {
  package arith;
}

problem
  :	operator EOF!
  ;

operator
	:	ADD
	| SUB
	|	MULT
	|	DIV
	|	FRACADD
	|	FRACSUB
	|	FRACMULT
	|	FRACDIV
	| EXPADD
	| EXPSUB
	| EXPMULT
	| EXPDIV
	;

evaluator
  : assignment* expression EOF!
  /*| factor EOF!*/
  ;

assignment
  : IDENT ':=' expression ';'
  ;

//expressions
term
  : IDENT
  |  '('! expression ')'!
  | INTEGER
  |	FRAC
  |	EXP
  | FACTOR
  | GCF
  | LCM
  | ASSOC
  | DIST
  ;
/*  
factor
	: FACTOR ':=' term
	;
 */ 
/*negation : 'not'* term;*/

unary
  : ('+'! | negation^ )* term
  ;

negation
  :  '-' -> NEGATION
  ;

mult
  : unary (('*'^ | '/'^ | 'mod'^ | 'times'^	|	'divides'^) unary)*
  ;

expression
  : mult (('+'^ | '-'^ | 'plus'^ | 'minus'^ | 'eMult'^ | 'eDiv'^) mult)*;

fragment LETTER : ('a'..'z' | 'A'..'Z');
fragment DIGIT : '0'..'9';
INTEGER : DIGIT+;
IDENT  : LETTER (LETTER | DIGIT)*;
ADD	: '<add>';
SUB : '<sub>';
MULT	: '<mult>';
DIV	:	'<div>';
FRAC	:	'<frac>';
EXP	:	'<exp>';
FRACADD	:	'<fracAdd>';
FRACSUB	:	'<fracSub>';
FRACMULT	:	'<fracMult>';
FRACDIV	:	'<fracDiv>';
EXPADD : '<expAdd>';
EXPSUB : '<expSub>';
EXPMULT : '<expMult>';
EXPDIV : '<expDiv>';
FACTOR : '<factor>';
GCF : '<gcf>';
LCM : '<lcm>';
ASSOC : '<assoc>';
DIST : '<dist>';
WS: (' ' | '\t' | '\n' | '\r' | '\f')+ {$channel = HIDDEN;};
